using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace SpoonCore2.Tools
{
	public class SyncBlockingRingBuffer<T>
	{
		private long _lastId = -1;
		private readonly SortedList<long, T> _data = new SortedList<long, T>();
		private readonly int _capacity;
		private readonly AutoResetEvent _reseter = new AutoResetEvent(false);

		public SyncBlockingRingBuffer(int capacity)
		{
			_capacity = capacity;
		}

		public int Count {get{ return _data.Count;}}

		public void Enqueue(long id, T item)
		{
			Monitor.Enter(_data);
			if (_data.Count == _capacity)
			{
				_data.Remove(_data.Keys[0]);
				_lastId = _data.Keys[0] - 1;
			}
			if(!_data.ContainsKey(id))_data.Add(id, item);
			Monitor.Exit(_data);

			_reseter.Set();
		}

		public T Dequeue()
		{
			Monitor.Enter(_data);
			while(_data.Count == 0)
			{
				Monitor.Exit(_data);
				_reseter.WaitOne();
				Monitor.Enter(_data);
			}

			if (_lastId == -1) _lastId = _data.Keys[0];
			
			long key = _data.Keys[0];
			while(_lastId + 1 < key)
			{
				Monitor.Exit(_data);
				_reseter.WaitOne();
				Monitor.Enter(_data);
				key = _data.Keys[0];
			}

			T res = _data[key];
			_lastId = key;
			_data.Remove(key);
			Monitor.Exit(_data);
			
			return res;
		}

		public static void Main()
		{
			
		}
	}
}